/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iluscodefx;

import excepciones.InterpreteException;
import iluscodelogica.Interprete;
import iluscodelogica.Observador;
import iluscodelogica.Sujeto;
import javafx.scene.shape.*;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.animation.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Bounds;



import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;

import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.util.Duration;

/**
 * CLASE CONTROLADORA DE LA INTERFAZ GRAFICA DE JAVAFX GUI.fxml
 *
 * @author fernanxi
 */
public class Controller implements Initializable, Observador {

    @FXML
    Button btnSIOK;
    @FXML
    Button btnSINOOK;
    @FXML
    Button btnMIENTRASOK;
    @FXML
    Button btnNewLine;
    @FXML
    Button btnDropCell;
    @FXML
    Pane caja;
    @FXML
    Label lab;
    @FXML
    CheckBox check2daCONDSI;
    @FXML
    CheckBox check2daCONDMIENTRAS;
    @FXML
    Button btnActivarAlarma;
    @FXML
    Button btnCerrarCerramiento;
    @FXML
    Button btnAvanzar;
    @FXML
    Button btnRecorrer;
    @FXML
    Button nuevoCodigo;
    @FXML
    Button detener;
    @FXML
    Rectangle pared1;
    @FXML
    Rectangle pared2;
    @FXML
    Rectangle pared3;
    @FXML
    Rectangle pared4;
    @FXML
    Rectangle pared5;
    @FXML
    Rectangle puerta1;
    @FXML
    Rectangle puerta2;
    @FXML
    Rectangle puerta3;
    @FXML
    Rectangle puerta4;
    @FXML
    Rectangle alarma1;
    @FXML
    Rectangle alarma2;
    @FXML
    Rectangle alarma3;
    @FXML
    Rectangle cerramiento1;
    @FXML
    Rectangle cerramiento2;
    @FXML
    Rectangle cerramiento3;
    @FXML
    Rectangle fuego;
    @FXML
    Rectangle base;
    @FXML
    Label etiqueta;
    @FXML
    Slider velocidad;
    @FXML
    ListView<HBox> list1 = new ListView<HBox>();
    ObservableList<HBox> lines = FXCollections.observableArrayList();
    ListView<String> list = new ListView<String>();
    ObservableList<String> codelines = FXCollections.observableArrayList();
    ArrayList<Rectangle> obstaculos = new ArrayList();
    ArrayList<Rectangle> alarmas = new ArrayList();
    ArrayList<Rectangle> cerramientos = new ArrayList();
    private Sujeto sujetoRobot;
    private boolean hayObstaculo;
    private boolean hayLadron;
    private boolean hayFuego;
    private String lineasCodigo;
    @FXML
    private ImageView robot;

    public String getLineasCodigo() {
        return lineasCodigo;
    }

    public void setLineasCodigo(String lineasCodigo) {
        this.lineasCodigo = lineasCodigo;
    }

    public boolean esAccion(String instruccion) {
        if (instruccion.equalsIgnoreCase("Avanzar") || instruccion.equalsIgnoreCase("ActivarAlarma") || instruccion.equalsIgnoreCase("CerrarCerramiento") || instruccion.equalsIgnoreCase("GirarNorte") || instruccion.equalsIgnoreCase("GirarSur") || instruccion.equalsIgnoreCase("GirarEste") || instruccion.equalsIgnoreCase("GirarOeste")) {
            return true;
        } else {
            return false;
        }
    }

    public boolean esBucle(String bucle) {
        if ((bucle.contains("SI") || bucle.contains("SINO") || bucle.contains("REPETIR") || bucle.contains("MIENTRAS")) && !bucle.contains("FIN ")) {
            return true;
        } else {
            return false;
        }
    }

    //Funcion para pasarle a la logica el string del algoritmo.
    @FXML
    public String recorrer() {
        String s1 = "";
        codelines.clear();
        ChoiceBox cb = new ChoiceBox();
        cb.setItems(FXCollections.observableArrayList("HayFuego", "HayObstaculo", "HayLadron", "NoHayObstaculo", "NoHayLadron", "NoHayFuego"));

        HBox aux;

        for (int x = 0; x <= lines.size() - 1; x++) {

            if (lines.get(x).getChildren().get(0).getId().equals("linea")) {
                lines.remove(x);
            }
        }

        for (int i = 0; i <= lines.size() - 1; i++) //este for itera verticalmente
        {
            String l = " ";

            for (int j = 0; j <= lines.get(i).getChildren().size() - 1; j++) //este for itera horizontalmente
            {

                String s = lines.get(i).getChildren().get(j).getId();
                switch (s) {
                    case "lb":
                        Label lbSI = (Label) lines.get(i).getChildren().get(j);
                        String tSI = lbSI.getText().toString();
                        l = l + tSI;
                        //Evaluacion si es accion
                        if (this.esAccion(tSI)) {
                            Label test = (Label) lines.get(i + 1).getChildren().get(0);
                            if (!test.getText().toString().contains("FIN")) {

                                if (!test.getText().toString().contains("FINPROGRAMA")) {
                                    l = l + ";";
                                } else {
                                    l = l;
                                }

                            }

                        }

                        if (this.esAccion(tSI)) {

                            Label test = (Label) lines.get(i - 1).getChildren().get(0);
                            
                            if (test.getText().toString().contains("FIN")) {

                                l = ";" + l;

                            }

                        }

                        if (this.esBucle(tSI)) {

                            if (!this.esBucle("SINO")) {

                                Label test = (Label) lines.get(i - 1).getChildren().get(0);
                                
                                if (test.getText().toString().contains("FIN")) {

                                    l = ";" + l;

                                }
                            }



                        }

                        break;
                    case "cb":
                        ChoiceBox cb1 = (ChoiceBox) lines.get(i).getChildren().get(j);
                        String tCN1 = cb1.getSelectionModel().getSelectedItem().toString();
                        l = l + tCN1;
                        break;
                    case "tf":
                        TextField tf = (TextField) lines.get(i).getChildren().get(j);
                        l = l + tf.getText();

                }
            }
            codelines.add(l);
        }

        for (int i = 0; i < codelines.size(); i++) {
            s1 = s1.concat(codelines.get(i).toString());            

            if (codelines.get(i).toString().contains(" FIN")) {
                if (this.esAccion(codelines.get(i).toString())) {

                    s1 = s1.concat(";");
                }

            }

        }

        return s1;


    }

    //Metodos para modificar el algoritmo (Grafica)
    public void sino(int i) {
        ArrayList al = new ArrayList();
        HBox b = new HBox();
        b.setStyle("-fx-background-color: #FFB318;");
        Label sino = new Label("SINO");
        sino.setId("lb");


        b.getChildren().add(sino);
        lines.add(i, b);

        HBox inicio = new HBox();
        Label lblInicio = new Label("INICIO");
        lblInicio.setId("lb");
        lblInicio.setStyle("-fx-background-color: #FFB318;");
        inicio.getChildren().add(lblInicio);
        lines.add(i + 1, inicio);


        HBox d = new HBox();
        d.setId("blanca");
        Label blanc = new Label();
        blanc.setId("linea");
        d.getChildren().add(blanc);
        lines.add(i + 2, d);

        HBox fin = new HBox();
        Label lblFin = new Label("FIN");
        lblFin.setId("lb");
        lblFin.setStyle("-fx-background-color: #FFB318;");
        fin.getChildren().add(lblFin);
        lines.add(i + 3, fin);

        list1.setItems(lines);

    }

    public void si(int i, boolean doscond) {
        //contenedores
        ArrayList al = new ArrayList();
        HBox b = new HBox();
        b.setStyle("-fx-background-color: #159EFF;");
        //condiciones
        //Condicion1
        ChoiceBox cbc1 = new ChoiceBox();
        cbc1.setId("cb");
        cbc1.setItems(FXCollections.observableArrayList("HayFuego", "HayObstaculo", "HayLadron", "NoHayObstaculo", "NoHayLadron", "NoHyaFuego"));
        //Operador
        ChoiceBox cbc2 = new ChoiceBox();
        cbc2.setId("cb");
        cbc2.setItems(FXCollections.observableArrayList("Y", "O"));
        //condicion 2
        ChoiceBox cbc3 = new ChoiceBox();
        cbc3.setId("cb");
        cbc3.setItems(FXCollections.observableArrayList("HayFuego", "HayObstaculo", "HayLadron", "NoHayObstaculo", "NoHayLadron", "NoHyaFuego"));
        //palabras reservadas
        Label si = new Label("SI ");
        Label entonces = new Label(" ENTONCES");
        si.setId("lb");
        entonces.setId("lb");
        //guardado
        b.getChildren().add(si);
        b.getChildren().add(cbc1);
        if (doscond) {
            b.getChildren().add(cbc2);
            b.getChildren().add(cbc3);
            b.getChildren().add(entonces);
        } else {
            b.getChildren().add(entonces);
        }

        lines.add(i, b); //agrego la primer linea

        HBox inicio = new HBox();
        Label lblInicio = new Label("INICIO");
        lblInicio.setId("lb");
        lblInicio.setStyle("-fx-background-color: #159EFF;");
        inicio.getChildren().add(lblInicio);
        lines.add(i + 1, inicio);


        HBox d = new HBox();
        d.setId("blanca");
        Label blanc = new Label();
        blanc.setId("linea");
        d.getChildren().add(blanc);
        lines.add(i + 2, d);

        HBox fin = new HBox();
        Label lblFin = new Label("FIN");
        lblFin.setId("lb");
        lblFin.setStyle("-fx-background-color: #159EFF;");
        fin.getChildren().add(lblFin);
        lines.add(i + 3, fin);


        //lines.add(blanca);
        list1.setItems(lines);
    }

    @FXML
    public void btnSIOK(ActionEvent event) {
        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();
            this.si(i, check2daCONDSI.isSelected());
        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();
                this.si(i, check2daCONDSI.isSelected());
            } else {
                int i = list1.getItems().size();
                this.si(i, check2daCONDSI.isSelected());
            }
        }
    }

    @FXML
    public void btnSINOOK(ActionEvent event) {
        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();
            this.sino(i);
        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();
                this.sino(i);
            } else {
                int i = list1.getItems().size();
                this.sino(i);
            }
        }
    }

    public void mientras(int i, boolean doscond) {
        ArrayList al = new ArrayList();
        HBox b = new HBox();
        b.setStyle("-fx-background-color: #39D029;");
        //condiciones
        //Condicion1
        ChoiceBox cbc1 = new ChoiceBox();
        cbc1.setId("cb");
        cbc1.setItems(FXCollections.observableArrayList("HayFuego", "HayObstaculo", "HayLadron", "NoHayObstaculo", "NoHayLadron", "NoHyaFuego"));
        //Operador
        ChoiceBox cbc2 = new ChoiceBox();
        cbc2.setId("cb");
        cbc2.setItems(FXCollections.observableArrayList("Y", "O"));
        //condicion 2
        ChoiceBox cbc3 = new ChoiceBox();
        cbc3.setId("cb");
        cbc3.setItems(FXCollections.observableArrayList("HayFuego", "HayObstaculo", "HayLadron", "NoHayObstaculo", "NoHayLadron", "NoHyaFuego"));
        //palabras reservadas
        Label si = new Label("MIENTRAS ");
        Label entonces = new Label(" HACER");
        si.setId("lb");
        entonces.setId("lb");
        //guardado
        b.getChildren().add(si);
        b.getChildren().add(cbc1);
        if (doscond) {
            b.getChildren().add(cbc2);
            b.getChildren().add(cbc3);
            b.getChildren().add(entonces);
        } else {
            b.getChildren().add(entonces);
        }

        lines.add(i, b); //agrego la primer linea
        HBox inicio = new HBox();
        Label lblInicio = new Label("INICIO");
        lblInicio.setId("lb");
        lblInicio.setStyle("-fx-background-color: #39D029;");
        inicio.getChildren().add(lblInicio);
        lines.add(i + 1, inicio);


        HBox d = new HBox();
        d.setId("blanca");
        Label blanc = new Label();
        blanc.setId("linea");
        d.getChildren().add(blanc);
        lines.add(i + 2, d);

        HBox fin = new HBox();
        Label lblFin = new Label("FIN");
        lblFin.setId("lb");
        lblFin.setStyle("-fx-background-color: #39D029;");
        fin.getChildren().add(lblFin);
        lines.add(i + 3, fin);





        list1.setItems(lines);

    }

    @FXML
    public void btnMIENTRASOK(ActionEvent event) {
        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();
            this.mientras(i, check2daCONDMIENTRAS.isSelected());
        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();
                this.mientras(i, check2daCONDMIENTRAS.isSelected());
            } else {
                int i = list1.getItems().size();
                this.mientras(i, check2daCONDMIENTRAS.isSelected());
            }
        }
    }

    public void repetir(int i) {
        ArrayList al = new ArrayList();
        HBox b = new HBox();
        b.setStyle("-fx-background-color: #9D78BA;");
        //condiciones
        //Condicion1
        TextField tf = new TextField() {

            @Override
            public void replaceText(int start, int end, String text) {
                if (!text.matches("[a-z, A-Z]")) {
                    super.replaceText(start, end, text);
                }

            }

            @Override
            public void replaceSelection(String text) {
                if (!text.matches("[a-z, A-Z]")) {
                    super.replaceSelection(text);
                }
            }
        };
        tf.setPrefColumnCount(2);
        tf.setId("tf");


        //palabras reservadas
        Label rep = new Label("REPETIR ");
        Label vec = new Label(" VECES");
        rep.setId("lb");
        vec.setId("lb");
        //guardado
        b.getChildren().add(rep);
        b.getChildren().add(tf);
        b.getChildren().add(vec);


        lines.add(i, b); //agrego la primer linea
        HBox inicio = new HBox();
        Label lblInicio = new Label("INICIO");
        lblInicio.setId("lb");
        lblInicio.setStyle("-fx-background-color: #9D78BA;");
        inicio.getChildren().add(lblInicio);
        lines.add(i + 1, inicio);


        HBox d = new HBox();
        d.setId("blanca");
        Label blanc = new Label();
        blanc.setId("linea");
        d.getChildren().add(blanc);
        lines.add(i + 2, d);

        HBox fin = new HBox();
        Label lblFin = new Label("FIN");
        lblFin.setId("lb");
        lblFin.setStyle("-fx-background-color: #9D78BA;");
        fin.getChildren().add(lblFin);
        lines.add(i + 3, fin);
        list1.setItems(lines);

    }

    @FXML
    public void btnREPETIROK(ActionEvent event) {
        try {
            if (list1.getSelectionModel().isEmpty()) {
                int i = list1.getItems().size();
                this.repetir(i);
            } else {
                if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                    int i = list1.getSelectionModel().getSelectedIndex();
                    this.repetir(i);
                } else {
                    int i = list1.getItems().size();
                    this.repetir(i);
                }
            }
        } catch (Exception e) {
        }
    }

    @FXML
    public void newLine(ActionEvent event) {
        HBox d = new HBox();
        d.setId("blanca");
        Label blanc = new Label();
        blanc.setId("linea");
        d.getChildren().add(blanc);


        if (list1.getSelectionModel().isEmpty()) {
            lines.add(d);
        } else {
            lines.add(list1.getSelectionModel().getSelectedIndex() + 1, d);
        }
        list1.setItems(lines);
    }

    @FXML
    public void borrarSeleccion(ActionEvent event) {

        lines.remove(list1.getSelectionModel().getSelectedIndex());

    }

    @FXML
    public void avanzar(ActionEvent event) {
        HBox hbavanzar = new HBox();
        hbavanzar.setStyle("-fx-background-color: #5BD9D7;");
        Label lbavanzar = new Label("Avanzar");
        lbavanzar.setId("lb");

        hbavanzar.getChildren().add(lbavanzar);


        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();

            lines.add(i, hbavanzar);
            list1.setItems(lines);

        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();


                lines.add(i, hbavanzar);
                list1.setItems(lines);
            } else {
                int i = list1.getItems().size();


                lines.add(i, hbavanzar);
                list1.setItems(lines);
            }
        }
    }

    @FXML
    public void labelGenerico(ActionEvent event, String metodo) {
        HBox hb = new HBox();
        Label lb = new Label();
        switch (metodo) {
            case "ActivarAlarma":
                lb.setText("ActivarAlarma");
                hb.setStyle("-fx-background-color: #FF4949;");
                break;
            case "Cerrar":
                lb.setText("CerrarCerramiento");
                hb.setStyle("-fx-background-color: #BBBCD4;");
                break;
            case "GirarNorte":
                lb.setText("GirarNorte");
                hb.setStyle("-fx-background-color: #C476FF;");
                break;
            case "GirarSur":
                lb.setText("GirarSur");
                hb.setStyle("-fx-background-color: #E6FF3E;");
                break;
            case "GirarEste":
                lb.setText("GirarEste");
                hb.setStyle("-fx-background-color: #4E57FF;");
                break;
            case "GirarOeste":
                lb.setText("GirarOeste");
                hb.setStyle("-fx-background-color: #FCA832;");
                break;

        }

        lb.setId("lb");
        hb.getChildren().add(lb);


        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();

            lines.add(i, hb);
            list1.setItems(lines);

        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();


                lines.add(i, hb);
                list1.setItems(lines);
            } else {
                int i = list1.getItems().size();


                lines.add(i, hb);
                list1.setItems(lines);
            }
        }
    }

    @FXML
    public void cerrarCerramiento(ActionEvent event) {
        this.labelGenerico(event, "Cerrar");
    }

    @FXML
    public void activarAlarma(ActionEvent event) {
        this.labelGenerico(event, "ActivarAlarma");
    }

    @FXML
    public void girarNorte(ActionEvent event) {
        this.labelGenerico(event, "GirarNorte");
    }

    @FXML
    public void girarSur(ActionEvent event) {
        this.labelGenerico(event, "GirarSur");
    }

    @FXML
    public void girarEste(ActionEvent event) {
        this.labelGenerico(event, "GirarEste");
    }

    @FXML
    public void girarOeste(ActionEvent event) {
        this.labelGenerico(event, "GirarOeste");
    }

    @FXML
    public void permutarArriba(ActionEvent event) {

        HBox aux = lines.get(list1.getSelectionModel().getSelectedIndex() - 1);
        lines.set(list1.getSelectionModel().getSelectedIndex() - 1, lines.get(list1.getSelectionModel().getSelectedIndex()));
        lines.set(list1.getSelectionModel().getSelectedIndex(), aux);
        list1.getSelectionModel().select(list1.getSelectionModel().getSelectedIndex() - 1);
    }

    @FXML
    public void permutarAbajo(ActionEvent event) {

        HBox aux = lines.get(list1.getSelectionModel().getSelectedIndex() + 1);
        lines.set(list1.getSelectionModel().getSelectedIndex() + 1, lines.get(list1.getSelectionModel().getSelectedIndex()));
        lines.set(list1.getSelectionModel().getSelectedIndex(), aux);
        list1.getSelectionModel().select(list1.getSelectionModel().getSelectedIndex() + 1);
    }

    //Hasta aca van los procedimientos para crear el algoritmo
    //Metodo para pruebas, se puede eliminar.
    @FXML
    public void avanzarTest(ActionEvent event) {

        try {

            trasladarRobotOrigen();

            codelines.clear();
            String palabras = recorrer();            
            Interprete inter = new Interprete(palabras);
            sujetoRobot = inter.getRobot();
            inter.compilarArchivo();
            inter.getRobot().start();
            inter.getRobot().agregarObservador(this);
            this.sujetoRobot.solicitarVelocidad(darVelociadad());
        } catch (InterpreteException ex) {
            etiqueta.setText(ex.getMensaje());
        }
    }

    public void trasladarRobotOrigen() {
        robot.translateXProperty().setValue(0);
        robot.translateYProperty().setValue(0);
        robot.rotateProperty().setValue(90);
    }

    @FXML
    public void nuevoCodigo() {

        lines.clear();
        etiqueta.setText("Bienvenido a IlusCode");

        robot.translateXProperty().setValue(0);
        robot.translateYProperty().setValue(0);
        robot.rotateProperty().setValue(90);
        
        palabraPrograma();
        palabraEjecucion();


    }

    public void limpiarLista() {
    }

    @FXML
    public void sacarUltimaComa() {
    }

    public void palabraEjecucion() {
        ArrayList al = new ArrayList();
        HBox b = new HBox();
        b.setStyle("-fx-background-color: #39D029;");

        //palabras reservadas
        Label inicioEjecucion = new Label("INICIOEJECUCION");

        inicioEjecucion.setId("lb");

        //guardado
        b.getChildren().add(inicioEjecucion);

        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();

            lines.add(i, b);
            list1.setItems(lines);
            HBox d = new HBox();
            d.setId("blanca");
            Label blanc = new Label();
            blanc.setId("linea");
            d.getChildren().add(blanc);
            lines.add(i + 1, d);
            //segunda linea
            HBox c = new HBox();
            c.setStyle("-fx-background-color: #5BD9D7;");
            Label finEjecucion = new Label("FINPROGRAMA");
            finEjecucion.setId("lb");
            c.getChildren().add(finEjecucion);
            lines.add(i + 2, c);

            list1.setItems(lines);
        }
    }

    public void palabraPrograma() {

        HBox hbPrograma = new HBox();
        hbPrograma.setStyle("-fx-background-color: #5BD9D7;");
        Label lblPrograma = new Label("PROGRAMA");
        lblPrograma.setId("lb");
        hbPrograma.getChildren().add(lblPrograma);



        if (list1.getSelectionModel().isEmpty()) {
            int i = list1.getItems().size();

            lines.add(i, hbPrograma);
            list1.setItems(lines);

        } else {
            if (list1.getSelectionModel().selectedItemProperty().get().getId().equals("blanca")) {
                int i = list1.getSelectionModel().getSelectedIndex();


                lines.add(i, hbPrograma);
                list1.setItems(lines);
            } else {
                int i = list1.getItems().size();


                lines.add(i, hbPrograma);
                list1.setItems(lines);
            }
        }

    }

    public Integer darVelociadad() {

        double dVel = velocidad.getValue();
        int veloci = (int) dVel;

        return veloci;
    }

    //Auxiliar para HayObstaculo
    public boolean opuestosCoinciden(Rectangle a, ImageView b, double rot) {
        boolean coinciden = false;
        switch ((int) rot) {
            case 0:
                if ((a.getBoundsInParent().getMaxX() - a.getWidth()) == b.getBoundsInParent().getMinX() + b.getFitWidth()) {
                    coinciden = true;
                }
                if (a.getBoundsInParent().getMaxX() == b.getBoundsInParent().getMinX()) {
                    coinciden = true;
                }
                break;

            case 180:
                if (a.getBoundsInParent().getMinX() == b.getBoundsInParent().getMaxX()) {
                    coinciden = true;
                }
                if ((a.getBoundsInParent().getMinX() + a.getWidth()) == b.getBoundsInParent().getMaxX() - b.getFitWidth()) {
                    coinciden = true;
                }
                break;


            case 90:
                if (a.getBoundsInParent().getMinY() == b.getBoundsInParent().getMaxY()) {
                    coinciden = true;
                }
                if ((a.getBoundsInParent().getMaxY()) == b.getBoundsInParent().getMinY()) {
                    coinciden = true;
                }
                break;

            case 270:
                if (a.getBoundsInParent().getMaxY() == b.getBoundsInParent().getMinY()) {
                    coinciden = true;
                }
                if ((a.getBoundsInParent().getMinY()) == b.getBoundsInParent().getMaxY()) {
                    coinciden = true;
                }
                break;

        }
        return coinciden;

    }

    //Metodos graficos
    public boolean hayObstaculoFX(double rot) {
        Bounds lb = robot.getBoundsInParent();
        Bounds lb2 = pared1.getBoundsInParent();
        boolean b = false;
        Line l = new Line();
        l.setEndX(robot.getBoundsInParent().getMinX());
        l.setEndY(robot.getBoundsInParent().getMinY());
        l.setStartX(robot.getBoundsInParent().getMinX() + lb.getWidth());
        l.setStartY(robot.getBoundsInParent().getMinY() + lb.getWidth());

        if (lb.getMinX() >= 0 || lb.getMinY() >= 0 || lb.getMaxY() <= 360 || lb.getMaxX() >= 360) {
            switch ((int) rot) {

                //norte   
                case 0:

                    if (!(lb.getMinY() <= 0.0)) {
                        for (Rectangle r : obstaculos) {
                            if (lb.intersects(r.getBoundsInParent())
                                    && r.getBoundsInParent().getMinY() < lb.getMinY()
                                    && r.getBoundsInParent().getMaxY() < lb.getMaxY()
                                    && !this.opuestosCoinciden(r, robot, rot)) {
                                b = true;
                            }
                        }
                    } else {
                        b = true;
                    }
                    break;
                //sur
                case 180:

                    if (!(lb.getMaxY() >= 600.0)) {
                        for (Rectangle r : obstaculos) {
                            if (lb.intersects(r.getBoundsInParent())
                                    && r.getBoundsInParent().getMinY() > lb.getMinY()
                                    && r.getBoundsInParent().getMaxY() > lb.getMaxY()
                                    && !this.opuestosCoinciden(r, robot, rot)) {
                                b = true;
                            }
                        }
                    } else {
                        b = true;
                    }
                    break;

                //este
                case 90:

                    if (!(lb.getMaxX() >= 400.0)) {
                        for (Rectangle r : obstaculos) {
                            if (lb.intersects(r.getBoundsInParent())
                                    && r.getBoundsInParent().getMaxX() > lb.getMaxX()
                                    && r.getBoundsInParent().getMinX() > lb.getMinX()
                                    && !this.opuestosCoinciden(r, robot, rot)) {
                                b = true;
                            }
                        }
                    } else {
                        b = true;
                    }
                    break;

                //oeste
                case 270:

                    if (!(lb.getMinX() <= 0.0)) {
                        for (Rectangle r : obstaculos) {
                            if (lb.intersects(r.getBoundsInParent())
                                    && r.getBoundsInParent().getMaxX() < lb.getMaxX()
                                    && r.getBoundsInParent().getMinX() < lb.getMinX()
                                    && !this.opuestosCoinciden(r, robot, rot)) {
                                b = true;
                            }
                        }
                    } else {
                        b = true;
                    }
                    break;
            }

            //return b;
        } else {
            b = true;

        }
        if (b) {
        }
        return b;
    }

    @FXML
    public boolean hayFuegoFX(double rot) {
        Bounds lb = robot.getBoundsInParent();
        Bounds bfuego = fuego.getBoundsInParent();
        boolean hay = false;


        if (lb.intersects(bfuego)) {
            for (Rectangle c : alarmas) {
                c.setFill(Color.RED);
                c.strokeProperty().set(Color.LIGHTSLATEGREY);

            }

            hay = true;

        }

        return hay;
    }

    @FXML
    public boolean hayLadronFX(double rot) {
        Bounds lb = robot.getBoundsInParent();

        boolean hay = false;

        return hay;
    }

    @FXML
    public void activarAlarmaFX() {

        for (Rectangle c : alarmas) {
            if (robot.getBoundsInParent().contains(c.getBoundsInParent())) {
                c.setFill(Color.RED);
                c.strokeProperty().set(Color.LIGHTSLATEGREY);
            }
        }


    }

    @FXML
    public void cerrarCerramientoFX() {
        for (Rectangle c : cerramientos) {
            if (robot.getBoundsInParent().contains(c.getBoundsInParent())) {
                c.setFill(Color.WHITE);
                c.strokeProperty().set(Color.web("#1000cc"));
            }
        }


    }

    //Metodos de Giro
    @FXML
    public void girarEsteFX() {

        robot.rotateProperty().setValue(90);

    }

    @FXML
    public void girarOEsteFX() {

        robot.rotateProperty().setValue(270);

    }

    @FXML
    public void girarNorteFX() {

        robot.rotateProperty().setValue(0);

    }

    @FXML
    public void girarSurFX() {

        robot.rotateProperty().setValue(180);

    }

    //Avance con control
    public void avanzarFX(double rot) {


        if (!this.hayObstaculoFX(rot)) {
            switch ((int) rot) {
                case 0:
                    double a = robot.getBoundsInParent().getMinY();
                    final TranslateTransition arriba = TranslateTransitionBuilder.create().node(robot).duration(Duration.millis(10)) //.fromX(rec.getBoundsInParent().getMinX())
                            .toY(robot.getBoundsInParent().getMinY() - 40).interpolator(Interpolator.LINEAR).cycleCount(1).build();
                    arriba.play();
                    break;
                case 90:
                    final TranslateTransition derecha = TranslateTransitionBuilder.create().node(robot).duration(Duration.millis(10)) //.fromX(rec.getBoundsInParent().getMinX())
                            .toX(robot.getBoundsInParent().getMinX() + 40).interpolator(Interpolator.LINEAR).cycleCount(1).build();
                    derecha.play();
                    break;
                case 180:
                    final TranslateTransition abajo = TranslateTransitionBuilder.create().node(robot).duration(Duration.millis(10)) //.fromX(rec.getBoundsInParent().getMinX())
                            .toY(robot.getBoundsInParent().getMinY() + 40).interpolator(Interpolator.LINEAR).cycleCount(1).build();
                    abajo.play();
                    break;

                case 270:
                    final TranslateTransition izquierda = TranslateTransitionBuilder.create().node(robot).duration(Duration.millis(10)) //.fromX(rec.getBoundsInParent().getMinX())
                            .toX(robot.getBoundsInParent().getMinX() - 40).interpolator(Interpolator.LINEAR).cycleCount(1).build();
                    izquierda.play();
                    break;
            }
        }

        this.sujetoRobot.solicitarInformacion(this.hayObstaculoFX(rot), this.hayFuegoFX(rot), this.hayLadronFX(rot));
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        obstaculos.add(fuego);
        obstaculos.add(pared1);
        obstaculos.add(pared2);
        obstaculos.add(pared3);
        obstaculos.add(pared4);
        obstaculos.add(pared5);

        alarmas.add(alarma1);
        alarmas.add(alarma2);
        alarmas.add(alarma3);

        cerramientos.add(cerramiento1);
        cerramientos.add(cerramiento2);
        cerramientos.add(cerramiento3);

        btnRecorrer.setStyle("-fx-base: rgb(30,170,255);");
        nuevoCodigo.setStyle("-fx-base: rgb(30,170,255);");





    }

    @Override
    public void actualizar(String instruccion) {


        if (instruccion.equals("avanzar")) {

            avanzarFX(robot.rotateProperty().getValue());

        } else if (instruccion.equals("giraroeste")) {

            girarOEsteFX();

        } else if (instruccion.equals("girareste")) {

            girarEsteFX();

        } else if (instruccion.equals("girarnorte")) {

            girarNorteFX();

        } else if (instruccion.equals("girarsur")) {

            girarSurFX();

        } else if (instruccion.equals("hayobstaculo")) {

            boolean obstaculo = hayObstaculoFX(robot.rotateProperty().getValue());
            boolean fuego = hayFuegoFX(robot.rotateProperty().getValue());
            boolean ladron = hayLadronFX(robot.rotateProperty().getValue());
            this.sujetoRobot.solicitarInformacion(obstaculo, fuego, ladron);

        } else if (instruccion.equals("hayfuego")) {

            boolean obstaculo = hayObstaculoFX(robot.rotateProperty().getValue());
            boolean fuego = hayFuegoFX(robot.rotateProperty().getValue());
            boolean ladron = hayLadronFX(robot.rotateProperty().getValue());
            this.sujetoRobot.solicitarInformacion(obstaculo, fuego, ladron);

        } else if (instruccion.equals("hayladron")) {

            boolean obstaculo = hayObstaculoFX(robot.rotateProperty().getValue());
            boolean fuego = hayFuegoFX(robot.rotateProperty().getValue());
            boolean ladron = hayLadronFX(robot.rotateProperty().getValue());
            this.sujetoRobot.solicitarInformacion(obstaculo, fuego, ladron);

        } else if (instruccion.equals("error")) {
            etiqueta.setText(instruccion);
        } else if (instruccion.equals("cerrarCerramiento")) {

            cerrarCerramientoFX();
        } else if (instruccion.equals("activaralarma")) {

            activarAlarmaFX();

        } else if (instruccion.equals("detener")) {

            activarAlarmaFX();
        }


    }

    public void leerSensor() {

        hayObstaculo = hayObstaculoFX(robot.rotateProperty().getValue());

    }
}
